<script lang="ts" setup>
import { ref, watch } from "vue";
import UniSearchBar from "@/components/uni-search-bar/index.vue";
import { AreaWeatherListType } from "@/type/index.ts";
import areas from "@/api/area/area.js";

let WXSDK = null;
let WXJSSDK = null;
const TX_MAP_KEY = "427BZ-W2IWV-ZNXPZ-U4D7M-2ACVS-XPBEB";
let longitude = 0;
let latitude = 0;

/**
 * 小程序--腾讯地图SDK
 */
// #ifdef MP-WEIXIN
WXSDK = require("../../static/js/qqmap-wx-jssdk.js");
WXJSSDK = new WXSDK({
  key: TX_MAP_KEY
});
// #endif

// 读取天气数据
const areaWeatherListStorage = uni.getStorageSync("areaWeatherList");
const areaWeatherList = ref<AreaWeatherListType[]>([]);
if (areaWeatherListStorage) {
  areaWeatherList.value = JSON.parse(areaWeatherListStorage);
}
const selectCityList = areaWeatherList.value.map((item: AreaWeatherListType) => item.areaName);
const locationArea = areaWeatherList.value.find((item: AreaWeatherListType) => item.location);

// 搜索关键词
const keyword = ref("");
// 定位城市
let locationAreaName = ref(locationArea ? locationArea.areaName : "");

// 省市县数据
const areasList = ref(areas);
for (const a of areasList.value) {
  a.unfold = false;
  for (const b of a.children) {
    b.unfold = false;
    for (const c of b.children) {
      // 设置是否选中
      c.select = selectCityList.includes(c.label);
    }
  }
}
// 拷贝一份省市县数
const originalAreasList = ref(JSON.parse(JSON.stringify(areasList.value)));

// 监听搜索
watch(keyword, () => {
  let list = JSON.parse(JSON.stringify(originalAreasList.value));
  for (const a of list) {
    // 有搜索内容时展开
    a.unfold = !!keyword.value;
    for (const b of a.children) {
      // 有搜索内容时展开
      b.unfold = !!keyword.value;
      // 过滤
      b.children = b.children.filter(c => c.label.includes(keyword.value));
    }
    // 过滤没有子级的
    a.children = a.children.filter(b => b.children.length);
  }
  // 过滤没有子级的
  list = list.filter(a => a.children.length);
  // 设置数据
  areasList.value = list;
});

/**
 * 取消
 */
const cancel = () => {
	uni.navigateBack({
		delta: 1
	});
};

/**
 * 改变是否展开
 */
const changeUnfold = (i: number, j: number) => {
  if (j !== undefined) {
    // 二级
    areasList.value[i].children[j].unfold = !areasList.value[i].children[j].unfold;
  } else {
    // 一级
    areasList.value[i].unfold = !areasList.value[i].unfold;
  }
};

/**
 * 选择城市
 */
const selectCity = item => {
  if (item.select) {
    // 已经选择的直接返回
    // 设置选中城市
    uni.setStorageSync("selectCity", item.label);
    uni.navigateBack({
      delta: 2
    });
  } else {
    // 没有选择过的弹出提示
    uni.showModal({
      title: "提示",
      content: "是否选择：" + item.label,
      success: e => {
        if (e.confirm) {
          // 选中
          item.select = true;
          // 设置选中城市
          uni.setStorageSync("selectCity", item.label);
          uni.navigateBack({
            delta: 2
          });
        }
      }
    });
  }
};

/**
 * 选择定位城市
 */
const selectLocationCity = () => {
  // 设置选中城市
  uni.setStorageSync("selectCity", locationAreaName.value);
  uni.navigateBack({
    delta: 2
  });
};

/**
 * 获取--经纬度
 */
const getLocationFn = () => {
  uni.showLoading({
    title: "定位中...",
    mask: true
  });
  // 定位
  uni.getLocation({
    type: "wgs84",
    success: res => {
      if (res.longitude) {
        // 设置经纬度
        longitude = res.longitude;
        latitude = res.latitude;
        // 获取--经纬度解析城市信息
        getCityInfoFn();
      } else {
        failInfoFn();
      }
    },
    fail: () => {
      failInfoFn();
    }
  });
};

/**
 * 获取--经纬度解析城市信息
 */
const getCityInfoFn = () => {
  // #ifdef APP
  getAppCityInfoFn();
  // #endif

  // #ifdef H5
  getH5CityInfoFn();
  // #endif

  // #ifdef MP-WEIXIN
  getWXCityInfoFn();
  // #endif
};

/**
 * 获取-APP经纬度解析城市信息
 */
const getAppCityInfoFn = () => {
  // 设置页面路径
  const path = `/hybrid/html/map.html?handle=getCityInfo&longitude=${longitude}&latitude=${latitude}`;
  // 设置webview
  const wv = plus.webview.create(path, "getCityInfo", {
    width: "0px",
    height: "0px"
  });
  // 显示webview
  wv.show();
  // 监听webview
  wv.overrideUrlLoading({ effect: "instant" }, res => {
    if (res && res.url && res.url.indexOf("myapp://getCityInfo") > -1) {
      // 关闭webview
      plus.webview.close(wv);
      // 获取城市
      let areaName = decodeURIComponent(res.url).split("areaName=")[1];
      if (areaName) {
        locationAreaName.value = areaName;
        uni.hideLoading();
      } else {
        failInfoFn();
      }
    } else {
      failInfoFn();
    }
  });
};

/**
 * 获取-H5经纬度解析城市信息
 */
const getH5CityInfoFn = () => {
  let geocoder = null;
  // 初始化‌地理编码
  AMap.plugin("AMap.Geocoder", () => {
    geocoder = new AMap.Geocoder({
      radius: 1000,
      extensions: "all"
    });
  });
  // 根据经纬度进行逆地理编码查询
  geocoder.getAddress([longitude, latitude], (status, res) => {
    if (status === "complete" && res.info === "OK") {
      if (res.regeocode && res.regeocode.formattedAddress) {
        // 获取城市
        locationAreaName.value = res.regeocode.addressComponent.district;
        uni.hideLoading();
      } else {
        failInfoFn();
      }
    } else {
      failInfoFn();
    }
  });
};

/**
 * 获取-小程序经纬度解析城市信息
 */
const getWXCityInfoFn = () => {
  // 初始化‌地理编码
  WXJSSDK.reverseGeocoder({
    sig: TX_MAP_KEY,
    location: {
      latitude: latitude,
      longitude: longitude
    },
    success: res => {
      if (res.result && res.result.address_component) {
        // 获取城市
        locationAreaName.value = res.result.address_component.district;
        uni.hideLoading();
      } else {
        failInfoFn();
      }
    },
    fail: () => {
      failInfoFn();
    }
  });
};

/**
 * 定位与解析失败处理
 */
const failInfoFn = () => {
  uni.hideLoading();
  uni.showToast({
    title: "定位失败，需要手动选择城市",
	icon: "error"
  });
};
</script>
<template>
  <view class="page-city-choose flex-column overflow-hidden">
    <UniSearchBar v-model="keyword" @cancel="cancel" placeholder="搜索城市" :show-cancel-btn="true" :autofocus="true" />
    <view class="m-t-20">
      <view class="p-b-20 f-s-28 flex flex-center">
        <text class="fa fa-map-marker m-r-10 f-s-30 color-primary"></text>
        <text class="flex1">定位城市</text>
        <view v-if="!locationAreaName" class="color-info f-s-28">未定位到你所在城市，请手动刷新</view>
      </view>
      <view class="flex flex-center">
        <view class="flex1">
          <button @click.stop="selectLocationCity" v-if="locationAreaName" type="primary" size="mini" class="flex flex-center">
            <text class="fa fa-map-marker m-r-10 f-s-30"></text>
            <text>{{ locationAreaName }}</text>
          </button>
        </view>
        <button v-if="!locationAreaName" @click="getLocationFn" type="primary" size="mini">重新定位</button>
      </view>
    </view>
    <view class="flex1 overflow-auto">
      <view v-for="(a, i) in areasList" :key="i">
        <view @click.stop="changeUnfold(i)" class="p-t-30 p-b-30 color-0 f-s-30 border-bottom flex flex-center">
          <view class="flex1">{{ a.label }}</view>
          <view class="flex flex-center">
            <text v-if="a.unfold" class="fa fa-angle-down color-6"></text>
            <text v-else class="fa fa-angle-right color-6"></text>
          </view>
        </view>
        <view v-show="a.unfold" class="p-l-20 box-sizing">
          <view @click.stop="changeUnfold(i, j)" v-for="(b, j) in a.children" :key="j">
            <view class="p-t-30 p-b-30 color-0 f-s-30 border-bottom flex flex-center">
              <view class="flex1">{{ b.label }}</view>
              <view class="flex flex-center">
                <text v-if="b.unfold" class="fa fa-angle-down color-6"></text>
                <text v-else class="fa fa-angle-right color-6"></text>
              </view>
            </view>
            <view v-show="b.unfold" class="p-l-20 box-sizing">
              <view @click.stop="selectCity(c)" v-for="(c, k) in b.children" :key="k" class="p-t-30 p-b-30 color-0 f-s-30 border-bottom flex flex-center">
                <text class="flex1">{{ c.label }}</text>
                <text v-if="c.select" class="fa fa-check-square color-primary"></text>
                <text v-else class="fa fa-square-o color-9"></text>
              </view>
            </view>
          </view>
        </view>
      </view>
      <view v-show="!areasList.length" class="flex flex-center h-200 color-info f-s-32">
        未搜索到对应的城市
      </view>
    </view>
  </view>
</template>
